package com.nbsaas.boot.order.ext.resource;

import com.nbsaas.boot.customer.api.apis.CustomerAddressApi;
import com.nbsaas.boot.customer.api.domain.response.CustomerAddressResponse;
import com.nbsaas.boot.order.api.apis.OrderAddressApi;
import com.nbsaas.boot.order.api.apis.OrderApi;
import com.nbsaas.boot.order.api.domain.field.OrderField;
import com.nbsaas.boot.order.api.domain.request.OrderAddressRequest;
import com.nbsaas.boot.order.api.domain.request.OrderItemRequest;
import com.nbsaas.boot.order.api.domain.response.OrderResponse;
import com.nbsaas.boot.order.data.repository.OrderRepository;
import com.nbsaas.boot.order.ext.apis.OrderExtApi;
import com.nbsaas.boot.order.ext.domain.request.OrderExtRequest;
import com.nbsaas.boot.pay.ext.apis.PaymentExtApi;
import com.nbsaas.boot.pay.ext.domain.request.OrderPayRequest;
import com.nbsaas.boot.product.api.apis.ProductApi;
import com.nbsaas.boot.product.api.apis.ProductSkuApi;
import com.nbsaas.boot.product.api.domain.response.ProductResponse;
import com.nbsaas.boot.product.api.domain.response.ProductSkuResponse;
import com.nbsaas.boot.promote.api.apis.CouponApi;
import com.nbsaas.boot.promote.api.domain.response.CouponResponse;
import com.nbsaas.boot.rest.filter.Filter;
import com.nbsaas.boot.rest.response.ResponseObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Date;


@Service
public class OrderExtResource implements OrderExtApi {

    @Resource
    private OrderRepository orderRepository;

    @Resource
    private CustomerAddressApi customerAddressApi;

    @Resource
    private OrderAddressApi orderAddressApi;

    @Resource
    private OrderApi orderApi;

    @Resource
    private CouponApi couponApi;

    @Resource
    private ProductApi productApi;


    @Resource
    private ProductSkuApi productSkuApi;

    @Resource
    private PaymentExtApi paymentExtApi;


    @Transactional(readOnly = true)
    @Override
    public ResponseObject<BigDecimal> sum() {
        ResponseObject<BigDecimal> result=new ResponseObject<>();
        result.setData(orderRepository.sumAmount());
        return result;
    }

    @Transactional
    @Override
    public ResponseObject<?> create(OrderExtRequest request) {
        ResponseObject<OrderResponse> result=new ResponseObject<>();

        request.setPlatformDiscount(BigDecimal.ZERO);
        request.setMerchantDiscount(BigDecimal.ZERO);
        request.setPointsDeduction(BigDecimal.ZERO);
        request.setVoucherDeduction(BigDecimal.ZERO);

        //如果需要收货地址，收货地址不能为空
        if (request.getDeliveryAddressId() == null) {
            result.setMsg("收货地址不能为空");
            result.setCode(501);
            return result;
        }
        CustomerAddressResponse address = customerAddressApi.oneData(Filter.eq("id", request.getDeliveryAddressId()));
        if (address == null) {
            result.setMsg("收货地址不存在");
            result.setCode(502);
            return result;
        }
        if (request.getItems() != null) {
            for (OrderItemRequest item : request.getItems()) {
                if (item.getSkuType() == null) {
                    item.setSkuType(1);
                }
                if (item.getSkuType() == 1) {
                    ProductResponse product = productApi.oneData(Filter.eq("id", item.getProductId()));
                    if (product == null) {
                        result.setMsg("商品不存在");
                        result.setCode(506);
                        return result;
                    }
                    item.setPrice(product.getPrice());
                }
                if (item.getSkuType() == 2) {
                    ProductSkuResponse product = productSkuApi.oneData(Filter.eq("id", item.getSkuId()));
                    if (product == null) {
                        result.setMsg("商品不存在");
                        result.setCode(506);
                        return result;
                    }
                    item.setPrice(product.getPrice());

                }
                if (item.getNum() == null) {
                    item.setNum(BigDecimal.ONE);
                }
                BigDecimal subTotal = item.getNum().multiply(item.getPrice());
                item.setTotal(subTotal);
            }
        }
        BigDecimal total = BigDecimal.ZERO;
        if (request.getItems() != null) {
            for (OrderItemRequest item : request.getItems()) {
                total = total.add(item.getTotal());
            }
            total = request.getItems().stream().map(OrderItemRequest::getTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
            request.setAmount(total);
        }

        if (request.getCouponId() != null) {

            CouponResponse coupon = couponApi.oneData(Filter.eq("id", request.getCouponId()));
            if (coupon == null) {
                result.setMsg("优惠券不存在");
                result.setCode(503);
                return result;
            }
            if (coupon.getState() == null) {
                coupon.setState(1);
            }
            if (coupon.getState() != 1) {
                result.setMsg("优惠券已失效");
                result.setCode(504);
                return result;
            }
            if (coupon.getUseBeginTime() != null && coupon.getUseBeginTime().after(new Date())) {
                result.setMsg("优惠券未开始使用");
                result.setCode(505);
                return result;
            }
            if (coupon.getUseEndTime() != null && coupon.getUseEndTime().before(new Date())) {
                result.setMsg("优惠券已过期");
                result.setCode(506);
                return result;
            }
            request.setMerchantDiscount(coupon.getDiscountAmount());
        }

        //计算所有优惠
        BigDecimal discount = request.getPlatformDiscount().
                add(request.getMerchantDiscount()).
                add(request.getPointsDeduction()).
                add(request.getVoucherDeduction());


        request.setTotalDiscount(discount);
        request.setActualPaymentAmount(request.getAmount().subtract(discount));

        //分摊优惠金额
        if (request.getItems() != null && request.getTotalDiscount().compareTo(BigDecimal.ZERO) > 0) {
            for (OrderItemRequest item : request.getItems()) {
                BigDecimal itemDiscount = item.getTotal().divide(request.getTotalDiscount(), MathContext.DECIMAL64);
                item.setTotalDiscount(itemDiscount);
                item.setActualAmount(item.getTotal().subtract(itemDiscount));
            }
        }

        request.setState(1);
        OrderResponse order = orderApi.createData(request);

        OrderAddressRequest addressRequest = new OrderAddressRequest();
        addressRequest.setAddress(address.getAddress());
        addressRequest.setCity(address.getCity());
        addressRequest.setOrder(order.getId());
        addressRequest.setArea(address.getArea());
        addressRequest.setLat(address.getLat());
        addressRequest.setLng(address.getLng());
        addressRequest.setProvince(address.getProvince());
        addressRequest.setPhone(address.getPhone());
        addressRequest.setPostalCode(address.getPostalCode());
        addressRequest.setNote(address.getNote());
        addressRequest.setTel(address.getTel());
        addressRequest.setConsignee(address.getName());

        orderAddressApi.createData(addressRequest);

        //处理付款
         result.setData(order);


        OrderPayRequest req=new OrderPayRequest();
        req.setDataId(order.getId());
        req.setPayHandler("orderPayHandler");
        req.setMoney(order.getActualPaymentAmount());
        req.setShop(order.getShop());
        req.setUser(order.getCustomerId());
        req.setOpenId(request.getOpenId());
        return  paymentExtApi.pay(req);
    }

    @Transactional
    @Override
    public ResponseObject<?> repay(OrderExtRequest request) {
        ResponseObject<?> result = new ResponseObject<>();

        OrderPayRequest req = new OrderPayRequest();
        OrderResponse order = orderApi.oneData(
                Filter.eq("id", request.getId()),
                Filter.eq(OrderField.customerId, request.getCustomerId())
        );

        if (order == null) {
            result.setMsg("订单不存在");
            result.setCode(503);
            return result;
        }
        if (order.getState() != 1) {
            result.setMsg("该订单不需要付款");
            result.setCode(504);
            return result;
        }
        req.setDataId(order.getId());
        req.setPayHandler("orderPayHandler");
        req.setMoney(order.getAmount());
        req.setShop(order.getShop());
        req.setUser(order.getCustomerId());
        req.setOpenId(request.getOpenId());
        return paymentExtApi.pay(req);
    }

    @Transactional
    @Override
    public ResponseObject<?> cancel(OrderExtRequest request) {
        ResponseObject<?> result = new ResponseObject<>();
        OrderResponse order = orderApi.oneData(
                Filter.eq("id", request.getId()),
                Filter.eq(OrderField.customerId, request.getCustomerId())
        );

        if (order.getState() != 1) {
            result.setMsg("订单状态不允许取消");
            result.setCode(504);
            return result;
        }

        if (order == null) {
            result.setMsg("订单不存在");
            result.setCode(503);
            return result;
        }
        request.setState(-2);
        orderApi.update(request);
        return result;
    }
}
